package handler

import (
	"encoding/json"
	"encoding/xml"
	"fmt"
	"github.com/julienschmidt/httprouter"
	"github.com/sashabaranov/go-openai"
	"io"
	"log"
	"net/http"
	"openwechat/config"
	"openwechat/gtp"
	"openwechat/logs"
	"openwechat/utils"
	"openwechat/utils/wxbizjsonmsgcrypt/epchat"
	"strings"
)

func WxMsgHandler(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
	httpStr := r.URL.RawQuery
	start := strings.Index(httpStr, "msg_signature=")
	start += len("msg_signature=")
	var msgSignature string
	next := getString(httpStr, "&timestamp=", start, &msgSignature)
	var timestamp string
	next = getString(httpStr, "&nonce=", next, &timestamp)
	nonce := httpStr[next:len(httpStr)]
	wxCpt := epchat.NewWXBizMsgCrypt(config.Config.Token, config.Config.EncodingAESKey, config.Config.ReceiverId)
	body, err := io.ReadAll(r.Body)
	if err != nil {
		log.Println("ReadAll Body fail")
		fmt.Fprintf(w, err.Error())
		return
	}
	msgContent := new(MsgContent)
	if err = xml.Unmarshal(body, msgContent); err != nil {
		log.Println("XML Unmarshal msgContent fail")
		fmt.Fprintf(w, err.Error())
		return
	}
	marshal, err := json.Marshal(epchat.WXBizJsonMsg4Recv{
		Tousername: msgContent.ToUsername,
		Encrypt:    msgContent.Encrypt,
		Agentid:    msgContent.Agentid,
	})
	if err != nil {
		log.Println("Marshal WXBizJsonMsg4Recv fail")
		fmt.Fprintf(w, err.Error())
		return
	}
	msg, err_ := wxCpt.DecryptMsg(msgSignature, timestamp, nonce, marshal)
	if err_ != nil {
		log.Println("DecryptMsg fail:", err_.ErrMsg)
		fmt.Fprintf(w, err.Error())
		return
	}
	if err = xml.Unmarshal(msg, &msgContent); nil != err {
		log.Println("Unmarshal fail:", err)
		fmt.Fprintf(w, err.Error())
		return
	}
	if msgContent.Event == Event {
		qusMsgs, err := getKfMessage(*msgContent)
		if err != nil {
			logs.Error(err.Error())
			return
		}
		for _, msg := range qusMsgs {
			msgContent.FromUsername = msg.ExternalUserid
			msgContent.Content = msg.Text.Content
			go gptReply(*msgContent, msg.MsgId)
		}
		fmt.Fprintf(w, "success")
		return
	}
	go gptReply(*msgContent, "")
	fmt.Fprintf(w, "success")
}

func gptReply(msgContent MsgContent, msgId string) {
	// 调openai
	choice, err := gtp.Openai(msgContent.FromUsername, msgContent.Content)
	if err != nil {
		logs.Error(err.Error())
		if msgContent.Event == Event {
			//给微信发消息
			if err = sendKfMsg("小助手有点走神,请稍后在来提问吧！", msgContent.FromUsername, msgContent.OpenKfId, msgId); err != nil {
				logs.Error("send weixin message fail:", err)
			}
			return
		}
		//给微信发消息
		if err = sendAppMsg("小助手有点走神,请稍后在来提问吧！", msgContent.FromUsername); err != nil {
			logs.Error("send weixin message fail:", err)
		}
		return
	}
	for _, reply := range choice {
		if reply.Message.Role != openai.ChatMessageRoleAssistant {
			continue
		}
		if msgContent.Event == Event {
			for _, msg := range utils.SplitString(reply.Message.Content, 2000) {
				//给微信发消息
				if err = sendKfMsg(msg, msgContent.FromUsername, msgContent.OpenKfId, msgId); err != nil {
					logs.Error("send weixin message fail:", err)
				}
			}
			return
		}
		//给微信发消息
		if err = sendAppMsg(reply.Message.Content, msgContent.FromUsername); err != nil {
			logs.Error("send weixin message fail:", err)
		}
	}
}
